Skip to content

feat: add manipulation planning groups#2489

Open
TomCC7 wants to merge 57 commits into
mainfrom
cc/spec/movegroup
Open

feat: add manipulation planning groups#2489
TomCC7 wants to merge 57 commits into
mainfrom
cc/spec/movegroup

Conversation

@TomCC7

@TomCC7 TomCC7 commented Jun 13, 2026

Copy link
Copy Markdown
Member

Summary

  • Add first-class manipulation planning groups: public robot/group IDs, global joint names, SRDF/fallback discovery, registry construction, and selector-aware world resolution.
  • Extend manipulation planning APIs so kinematics, planners, world monitors, and ManipulationModule can plan to group-scoped pose and joint targets while preserving local model joint names internally.
  • Carry generated plans through preview and execution: selected joints are projected in group order, coordinator trajectory tasks are resolved per robot, and multi-arm execution uses coordinator task names.
  • Improve IK/planning internals, including Pink IK model-context reuse, multi-frame solve sharing, seed-fallback guardrails, Drake/Jacobian/RRT group support, and optional end-effector handling.
  • Align robot/blueprint integration after the manipulator blueprint reorg, including OpenArm planner/coordinator scoped joint-state publishing and current dual-arm blueprint tests.
  • Keep only the thin visualization ABI compatibility layer needed by the new planning APIs. The full Viser planning-group UI now lives in stacked PR feat: add planning group Viser panel #2563.
  • Remove compatibility shims and clarify helper ownership: planning identifier grammar lives in groups/identifiers.py; joint target/state helpers live in groups/joints.py.
image

Stack

Verification

  • uv run pytest dimos/manipulation/planning/test_planning_group_identifiers.py dimos/manipulation/planning/test_planning_group_joints.py dimos/manipulation/planning/kinematics/test_pink_ik.py dimos/manipulation/test_manipulation_unit.py -q
  • uv run pytest dimos/manipulation/planning/kinematics -q
  • uv run pytest dimos/e2e_tests/test_manipulation_planning_groups.py -m self_hosted_large -q
  • uv run pytest dimos/e2e_tests/test_control_coordinator.py -q
  • uv run pytest dimos/robot/test_all_blueprints.py dimos/robot/test_all_blueprints_generation.py dimos/control/blueprints/test_dual.py -q
  • uv run pytest dimos/manipulation/visualization/test_factory.py dimos/manipulation/visualization/viser/test_viser_visualization.py dimos/manipulation/visualization/viser/test_visualizer_lifecycle.py dimos/manipulation/test_manipulation_unit.py -q
  • uv run --group lint mypy
  • uv run ruff check ... / uv run ruff format --check ...
  • rtk git diff --check

Notes

  • The PR has absorbed follow-up fixes from review and CI: empty target requests no longer fault the manipulation module before planning starts, pose planning now checks for a planner before entering the planning state, and joint-state reads no longer require an end-effector link.
  • Old Greptile inline comments may still appear on outdated diff positions, but the latest code includes the P1 fixes called out in the current review cycle.

@TomCC7 TomCC7 changed the title WIP spec: movegroup concept and bimanual/multi-target motion planning WIP spec: planning group and bimanual/multi-target motion planning Jun 13, 2026
@codecov

codecov Bot commented Jun 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.38037% with 693 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
dimos/manipulation/manipulation_module.py 54.26% 140 Missing and 26 partials ⚠️
...imos/manipulation/planning/planners/rrt_planner.py 55.39% 71 Missing and 20 partials ⚠️
dimos/manipulation/planning/world/drake_world.py 37.50% 67 Missing and 8 partials ⚠️
dimos/manipulation/planning/groups/discovery.py 67.26% 31 Missing and 24 partials ⚠️
dimos/manipulation/visualization/viser/adapter.py 26.66% 50 Missing and 5 partials ⚠️
...mos/manipulation/visualization/viser/visualizer.py 28.37% 50 Missing and 3 partials ⚠️
dimos/manipulation/planning/kinematics/pink_ik.py 81.14% 29 Missing and 17 partials ⚠️
dimos/manipulation/planning/groups/joints.py 55.55% 19 Missing and 9 partials ⚠️
...mos/manipulation/planning/monitor/world_monitor.py 71.11% 20 Missing and 6 partials ⚠️
...mos/e2e_tests/test_manipulation_planning_groups.py 84.48% 11 Missing and 7 partials ⚠️
... and 13 more
@@            Coverage Diff             @@
##             main    #2489      +/-   ##
==========================================
- Coverage   70.88%   70.86%   -0.03%     
==========================================
  Files         866      882      +16     
  Lines       77199    79843    +2644     
  Branches     6857     7211     +354     
==========================================
+ Hits        54725    56582    +1857     
- Misses      20671    21350     +679     
- Partials     1803     1911     +108     
Flag Coverage Δ
OS-ubuntu-24.04-arm 62.87% <73.35%> (-0.13%) ⬇️
OS-ubuntu-latest 65.49% <71.02%> (-0.35%) ⬇️
Py-3.10 65.49% <71.02%> (-0.34%) ⬇️
Py-3.11 65.49% <71.02%> (-0.34%) ⬇️
Py-3.12 65.49% <71.02%> (-0.34%) ⬇️
Py-3.13 65.49% <71.02%> (-0.34%) ⬇️
Py-3.14 65.50% <71.02%> (-0.34%) ⬇️
Py-3.14t 65.49% <71.02%> (-0.34%) ⬇️
SelfHosted-Large 29.97% <23.04%> (-0.13%) ⬇️
SelfHosted-Linux 37.39% <28.49%> (-0.43%) ⬇️
SelfHosted-macOS 36.25% <28.49%> (-0.36%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
dimos/control/test_control.py 94.82% <100.00%> (+0.26%) ⬆️
dimos/control/tick_loop.py 65.48% <100.00%> (+0.17%) ⬆️
.../planning/kinematics/test_jacobian_ik_selection.py 100.00% <100.00%> (ø)
dimos/manipulation/planning/spec/config.py 100.00% <100.00%> (+5.26%) ⬆️
dimos/manipulation/planning/spec/enums.py 100.00% <100.00%> (ø)
dimos/manipulation/planning/spec/protocols.py 100.00% <100.00%> (ø)
...lation/planning/test_planning_group_identifiers.py 100.00% <100.00%> (ø)
...anipulation/planning/test_planning_group_joints.py 100.00% <100.00%> (ø)
...imos/manipulation/planning/test_planning_groups.py 100.00% <100.00%> (ø)
...mos/manipulation/planning/utils/test_mesh_utils.py 100.00% <100.00%> (ø)
... and 32 more

... and 54 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TomCC7 TomCC7 changed the title WIP spec: planning group and bimanual/multi-target motion planning feat: add manipulation planning groups Jun 17, 2026
@TomCC7 TomCC7 changed the title feat: add manipulation planning groups WIP: feat: add manipulation planning groups Jun 17, 2026
Comment thread dimos/e2e_tests/test_manipulation_planning_groups.py Outdated
Comment thread dimos/manipulation/planning/kinematics/jacobian_ik.py Outdated
Comment thread dimos/manipulation/planning/kinematics/jacobian_ik.py
Comment thread dimos/manipulation/planning/kinematics/jacobian_ik.py Outdated
Comment thread dimos/manipulation/manipulation_module.py
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py
@TomCC7 TomCC7 force-pushed the cc/spec/movegroup branch from f157926 to 31731b1 Compare June 19, 2026 02:31
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py
Comment thread dimos/manipulation/manipulation_module.py
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/planning/world/drake_world.py Outdated
Comment thread dimos/manipulation/planning/planning_group_utils.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
Comment thread dimos/manipulation/manipulation_module.py Outdated
@TomCC7 TomCC7 requested a review from mustafab0 as a code owner June 22, 2026 05:10
@TomCC7 TomCC7 changed the title WIP: feat: add manipulation planning groups feat: add manipulation planning groups Jun 22, 2026
@greptile-apps

greptile-apps Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces first-class manipulation planning groups: public robot/group IDs, global joint names (robot/joint), SRDF/fallback discovery, a PlanningGroupRegistry, and group-scoped planning, IK, FK, and collision APIs throughout the manipulation stack. The GeneratedPlan model replaces per-robot path storage and carries global joint names through preview and execution.

  • New groups/ package (discovery.py, registry.py, models.py, identifiers.py, joints.py): backend-independent planning-group declaration, identifier grammar, and joint-target conversion helpers.
  • ManipulationModule refactor: plan_to_pose_targets, plan_to_joint_targets, inverse_kinematics, forward_kinematics, and check_collision replace the previous single-robot wrappers; execution now iterates over all affected robots in a plan.
  • Drake world and WorldMonitor updates: group-aware get_group_ee_pose, get_group_jacobian, animate_plan, and check_collision; ee_frame is now optional; _positions_for_robot_state adds named-joint validation on world state writes.

Confidence Score: 3/5

Planning for a single robot in a multi-robot setup will fault the module whenever any other robot has a stale state monitor, because _selected_joint_state now always queries the whole-world joint state instead of only the robots involved in the plan.

The key regression is in _selected_joint_state: it calls current_global_joint_state() which checks staleness for every registered robot before returning any start configuration. In a dual-arm setup this means a temporary connectivity blip on one arm blocks all planning on the other arm and sends the module into FAULT, requiring an explicit reset.

dimos/manipulation/manipulation_module.py (_selected_joint_state / current_global_joint_state interaction) and dimos/manipulation/planning/monitor/world_monitor.py (current_global_joint_state staleness check scope).

Important Files Changed

Filename Overview
dimos/manipulation/manipulation_module.py Major refactor: replaces per-robot planned-path storage with a single GeneratedPlan; adds group-scoped planning APIs. Contains a P1 regression where _selected_joint_state blocks all planning when any registered robot has stale state, and a P2 stale-plan-after-cancel regression from removing the planning-epoch guard.
dimos/manipulation/planning/groups/discovery.py New file: SRDF and fallback planning-group discovery. Well-structured with clear precedence. Chain-group parsing still discards groups when a fixed joint branches off an intermediate link.
dimos/manipulation/planning/groups/registry.py New file: backend-independent PlanningGroupRegistry. Clean implementation with duplicate-check guards.
dimos/manipulation/planning/world/drake_world.py Adds group-aware get_group_ee_pose, get_group_jacobian, animate_plan, and preview group routing. ee_frame is now optional.
dimos/manipulation/planning/monitor/world_monitor.py Adds PlanningGroupRegistry, current_global_joint_state, check_collision, and group-scoped APIs. current_global_joint_state is overly strict for single-group planning in multi-robot setups.
dimos/manipulation/planning/kinematics/pink_ik.py Major refactor: adds multi-frame and multi-robot IK via solve_pose_targets; separates model context from frame context; removes collision filtering from IK.
dimos/manipulation/visualization/viser/adapter.py Extensive compatibility shim work. get_planned_trajectory_duration returns waypoint count (len-1) rather than real seconds.
dimos/manipulation/visualization/viser/visualizer.py Adds animate_plan and _robot_path_for_plan for group-scoped preview. return-instead-of-continue in animate_plan remains unaddressed.
dimos/manipulation/planning/spec/config.py RobotModelConfig gains planning_groups with auto-fallback generation in model_post_init; end_effector_link is now Optional; base_pose defaults to identity.
dimos/manipulation/planning/planners/rrt_planner.py Major expansion: adds plan_selected_joint_path for group-scoped planning with global-to-local joint name conversion.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[plan_to_pose_targets / plan_to_joint_targets] --> B{pre-flight checks}
    B -->|fail| Z[return False]
    B -->|pass| C[_begin_planning state PLANNING]
    C --> D[_selected_joint_state current_global_joint_state ALL robots]
    D -->|any robot stale| E[_fail FAULT]
    D -->|fresh| F{pose or joint?}
    F -->|pose| G[inverse_kinematics PinkIK.solve_pose_targets]
    F -->|joint| H[joint_target_to_global_names]
    G --> I[_plan_selected_path planner.plan_selected_joint_path]
    H --> I
    I -->|fail| E
    I -->|success| J[store GeneratedPlan state COMPLETED]
    J --> K[preview_plan animate_plan]
    J --> L[execute_plan project local trajectories sequential coordinator dispatch]
    L --> M[_invoke_coordinator_task per affected robot]
    M -->|all ok| N[state COMPLETED]
    M -->|first fail| E
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[plan_to_pose_targets / plan_to_joint_targets] --> B{pre-flight checks}
    B -->|fail| Z[return False]
    B -->|pass| C[_begin_planning state PLANNING]
    C --> D[_selected_joint_state current_global_joint_state ALL robots]
    D -->|any robot stale| E[_fail FAULT]
    D -->|fresh| F{pose or joint?}
    F -->|pose| G[inverse_kinematics PinkIK.solve_pose_targets]
    F -->|joint| H[joint_target_to_global_names]
    G --> I[_plan_selected_path planner.plan_selected_joint_path]
    H --> I
    I -->|fail| E
    I -->|success| J[store GeneratedPlan state COMPLETED]
    J --> K[preview_plan animate_plan]
    J --> L[execute_plan project local trajectories sequential coordinator dispatch]
    L --> M[_invoke_coordinator_task per affected robot]
    M -->|all ok| N[state COMPLETED]
    M -->|first fail| E
Loading

Reviews (9): Last reviewed commit: "fix: restore dual xarm planner coordinat..." | Re-trigger Greptile

Comment thread dimos/manipulation/planning/world/drake_world.py Outdated
Comment thread dimos/manipulation/planning/world/drake_world.py
Comment thread dimos/manipulation/manipulation_module.py
Comment thread dimos/manipulation/manipulation_module.py
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jun 22, 2026
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Jun 22, 2026
Comment thread dimos/manipulation/manipulation_module.py Outdated
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jun 22, 2026
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Jun 22, 2026
Comment thread dimos/manipulation/planning/groups/discovery.py
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jun 22, 2026
@github-actions github-actions Bot added ready-to-merge Required CI checks have passed on this PR and removed ready-to-merge Required CI checks have passed on this PR labels Jun 22, 2026
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Jun 22, 2026
Comment thread dimos/manipulation/visualization/viser/visualizer.py
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jun 22, 2026
@github-actions github-actions Bot added ready-to-merge Required CI checks have passed on this PR and removed ready-to-merge Required CI checks have passed on this PR labels Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Planning groups Concurrent plannign for bimanual arms

1 participant